package com.hongtech.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hongtech.common.constant.Constant;
import com.hongtech.common.page.PageData;
import com.hongtech.common.service.CrudService;
import com.hongtech.common.utils.BeanCopierUtils;
import org.springframework.beans.BeanUtils;

import java.util.List;
import java.util.Map;

/**
 * 基于mybatis-plus封装CRUD基础服务类
 */
public abstract class CrudServiceImpl<M extends BaseMapper<T>, T, D>
        extends ServiceImpl<M, T> implements CrudService<T, D> {

    protected Class<D> currentDtoClass() {
        return (Class<D>) ReflectionKit
                .getSuperClassGenericType(getClass(), CrudServiceImpl.class, 2);
    }

    @Override
    public PageData<D> pages(Map<String, Object> pageParams, LambdaQueryWrapper<T> wrapper) {
        IPage<T> pages = baseMapper.selectPage(getPage(pageParams), wrapper);
        return getPageData(pages, currentDtoClass());
    }

    @Override
    public List<D> list(LambdaQueryWrapper<T> wrapper) {
        List<T> entityList = baseMapper.selectList(wrapper);
        return BeanCopierUtils.copyPropertiesList(entityList, currentDtoClass());
    }

    @Override
    public D get(Long id) {
        T entity = baseMapper.selectById(id);
        return BeanCopierUtils.copyProperties(entity, currentDtoClass());
    }

    @Override
    public void add(D dto) {
        T entity = BeanCopierUtils.copyProperties(dto, currentModelClass());
        baseMapper.insert(entity);
        BeanUtils.copyProperties(entity, dto);
    }

    @Override
    public void update(D dto) {
        T entity = BeanCopierUtils.copyProperties(dto, currentModelClass());
        updateById(entity);
    }

    @Override
    public int delete(List<Long> ids) {
        return baseMapper.deleteBatchIds(ids);
    }

    /**
     * 获取分页对象
     *
     * @param pageParams 分页查询参数
     */
    protected IPage<T> getPage(Map<String, Object> pageParams) {
        long curPage = 1;
        long limit = 10;
        if (pageParams.get(Constant.PAGE) != null) {
            curPage = Long.parseLong(String.valueOf(pageParams.get(Constant.PAGE)));
        }
        if (pageParams.get(Constant.LIMIT) != null) {
            limit = Long.parseLong(String.valueOf(pageParams.get(Constant.LIMIT)));
        }
        return new Page<>(curPage, limit);
    }

    /**
     * 获取分页数据
     *
     * @param page   分页对象
     * @param target 目标类
     */
    protected <T> PageData<T> getPageData(IPage page, Class<T> target) {
        return getPageData(page.getRecords(), page.getTotal(), target);
    }

    /**
     * 获取分页数据
     *
     * @param list   分页数据
     * @param total  总数
     * @param target 目标类
     */
    protected <T> PageData<T> getPageData(List<?> list, long total, Class<T> target) {
        List<T> targetList = BeanCopierUtils.copyPropertiesList(list, target);
        return new PageData<>(targetList, total);
    }

}
